/***************************************************************************
 *   Copyright (C) 2008 by Chris Bornholdt,,,   *
 *   amelek@dell   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 
#ifndef _CONVOLUTION_RESAMPLING_HPP_
#define _CONVOLUTION_RESAMPLING_HPP_

#include "convolution.hpp"
#include "convolutionkernels.hpp"
#include <boost/range.hpp>
#include <boost/range/concepts.hpp>
#include <boost/concept/requires.hpp>

template<typename SourceIterator, typename Kernel>
class resampling_wrapper
{
	public:
		typedef typename boost::RandomAccessIterator<SourceIterator>::value_type result_type;
	
		resampling_wrapper(SourceIterator source_begin, SourceIterator source_end, 
			Kernel kernel, unsigned int sample_size) : convolution_(source_begin, source_end, 
				kernel), sample_size_(sample_size)
		{	
			scale_ = static_cast<double>(std::distance(source_begin, source_end)) / 
				static_cast<double>(sample_size);	
		}
			
		result_type operator[](int n) const
		{	return (*this)(n);	}
		result_type operator()(double x) const
		{	return convolution_(-0.5 + (x + 0.5) * scale_);	}
		
		template<typename T>
		operator T() const
		{
			BOOST_CONCEPT_ASSERT((boost::Mutable_ForwardContainer<T>));
			
			T return_value(sample_size_);
			for(unsigned int i = 0; i < sample_size_; ++i)
				return_value[i] = (*this)[i];
				
			return return_value;
		}
			
	private:
		general_convolution<SourceIterator, Kernel, false> convolution_;
		unsigned int sample_size_;
		double scale_;
};


//TODO add proper freedom for RandomAccessRange to be non-double value_type
template<typename RandomAccessRange>
BOOST_CONCEPT_REQUIRES(
	((boost::RandomAccessRangeConcept<RandomAccessRange>)), 
	(resampling_wrapper<typename boost::range_iterator<const RandomAccessRange>::type, 
		bicubic_kernel<double> >))
bicubic_resampling(const RandomAccessRange& range, unsigned int sample_size)
{	
	return resampling_wrapper<typename boost::range_iterator<const RandomAccessRange
		>::type, bicubic_kernel<double> >
		(boost::begin(range), boost::end(range), bicubic_kernel<double>(), sample_size);
}
 	
 
 #endif
